package service

import (
	"context"
	"flare-admin/db/sqlc/ddos"
	"flare-admin/http/request"
	"flare-admin/service/dto"
	"time"

	"github.com/sirupsen/logrus"
)

// AddDDoSFlow 添加DDoS流量数据
func (s *Service) AddDDoSFlow(ctx context.Context, flowDTO ddos.InsertDDoSFlowParams) (int32, error) {
	id, err := s.dao.Ddos.InsertDDoSFlow(ctx, flowDTO)
	if err != nil {
		logrus.Errorf("[AddDDoSFlow] - failed to insert ddos flow: %v", err)
		return 0, err
	}
	logrus.Debugf("[AddDDoSFlow] - successfully inserted ddos flow with id: %d", id)
	
	// 触发数据同步
	if syncService := GetDDoSFlowSyncService(); syncService != nil {
		// 获取刚插入的数据并通知同步服务
		if dbFlow, err := s.dao.Ddos.SelectDDoSFlowsByTimeRange(ctx, ddos.SelectDDoSFlowsByTimeRangeParams{
			StartTime: time.Now().Add(-1 * time.Minute), // 获取最近1分钟的数据
			EndTime:   time.Now(),
		}); err == nil && len(dbFlow) > 0 {
			syncService.UpdateFlows(dbFlow)
		}
	}
	
	return id, nil
}

// AddDDoSFlowsBatch 批量添加DDoS流量数据
func (s *Service) AddDDoSFlowsBatch(ctx context.Context, flowsDTO []ddos.InsertDDoSFlowParams) error {
	for _, flowDTO := range flowsDTO {
		_, err := s.dao.Ddos.InsertDDoSFlow(ctx, flowDTO)
		if err != nil {
			logrus.Errorf("[AddDDoSFlowsBatch] - failed to insert ddos flow: %v", err)
			return err
		}
	}
	logrus.Debugf("[AddDDoSFlowsBatch] - successfully inserted %d ddos flows", len(flowsDTO))
	
	// 触发数据同步
	if syncService := GetDDoSFlowSyncService(); syncService != nil {
		// 获取刚插入的数据并通知同步服务
		if dbFlow, err := s.dao.Ddos.SelectDDoSFlowsByTimeRange(ctx, ddos.SelectDDoSFlowsByTimeRangeParams{
			StartTime: time.Now().Add(-1 * time.Minute), // 获取最近1分钟的数据
			EndTime:   time.Now(),
		}); err == nil && len(dbFlow) > 0 {
			syncService.UpdateFlows(dbFlow)
		}
	}
	
	return nil
}

// GetAllDDoSFlowsFromDB 从数据库获取所有DDoS流量数据
func (s *Service) GetAllDDoSFlowsFromDB(ctx context.Context) ([]ddos.OteldemoDdosFlow, error) {
	flows, err := s.dao.Ddos.SelectAllDDoSFlows(ctx)
	if err != nil {
		logrus.Errorf("[GetAllDDoSFlowsFromDB] - failed to get all ddos flows: %v", err)
		return nil, err
	}
	logrus.Debugf("[GetAllDDoSFlowsFromDB] - successfully retrieved %d ddos flows", len(flows))
	return flows, nil
}

// GetDDoSFlowsByType 根据流量类型获取DDoS流量数据
func (s *Service) GetDDoSFlowsByType(ctx context.Context, flowType string) ([]ddos.OteldemoDdosFlow, error) {
	flows, err := s.dao.Ddos.SelectDDoSFlowsByType(ctx, flowType)
	if err != nil {
		logrus.Errorf("[GetDDoSFlowsByType] - failed to get ddos flows by type %s: %v", flowType, err)
		return nil, err
	}
	logrus.Debugf("[GetDDoSFlowsByType] - successfully retrieved %d ddos flows of type %s", len(flows), flowType)
	return flows, nil
}

// GetDDoSFlowsByIP 根据IP获取DDoS流量数据
func (s *Service) GetDDoSFlowsByIP(ctx context.Context, ip string) ([]ddos.OteldemoDdosFlow, error) {
	flows, err := s.dao.Ddos.SelectDDoSFlowsByIP(ctx, ip)
	if err != nil {
		logrus.Errorf("[GetDDoSFlowsByIP] - failed to get ddos flows by ip %s: %v", ip, err)
		return nil, err
	}
	logrus.Debugf("[GetDDoSFlowsByIP] - successfully retrieved %d ddos flows for ip %s", len(flows), ip)
	return flows, nil
}

// GetDDoSFlowsByTimeRange 根据时间范围获取DDoS流量数据
func (s *Service) GetDDoSFlowsByTimeRange(ctx context.Context, startTime, endTime time.Time) ([]ddos.OteldemoDdosFlow, error) {
	flows, err := s.dao.Ddos.SelectDDoSFlowsByTimeRange(ctx, ddos.SelectDDoSFlowsByTimeRangeParams{
		StartTime: startTime,
		EndTime:   endTime,
	})
	if err != nil {
		logrus.Errorf("[GetDDoSFlowsByTimeRange] - failed to get ddos flows by time range: %v", err)
		return nil, err
	}
	logrus.Debugf("[GetDDoSFlowsByTimeRange] - successfully retrieved %d ddos flows in time range", len(flows))
	return flows, nil
}

// UpdateDDoSFlow 更新DDoS流量数据
func (s *Service) UpdateDDoSFlow(ctx context.Context, updateDTO ddos.UpdateDDoSFlowParams) error {
	_, err := s.dao.Ddos.UpdateDDoSFlow(ctx, updateDTO)
	if err != nil {
		logrus.Errorf("[UpdateDDoSFlow] - failed to update ddos flow: %v", err)
		return err
	}
	logrus.Debugf("[UpdateDDoSFlow] - successfully updated ddos flow with id: %d", updateDTO.ID)
	return nil
}

// DeleteDDoSFlow 删除DDoS流量数据
func (s *Service) DeleteDDoSFlow(ctx context.Context, id int32) error {
	err := s.dao.Ddos.DeleteDDoSFlow(ctx, id)
	if err != nil {
		logrus.Errorf("[DeleteDDoSFlow] - failed to delete ddos flow with id %d: %v", id, err)
		return err
	}
	logrus.Debugf("[DeleteDDoSFlow] - successfully deleted ddos flow with id: %d", id)
	return nil
}

// InitializeDDoSFlowsData 初始化DDoS流量数据到数据库
func (s *Service) InitializeDDoSFlowsData(ctx context.Context) error {
	// 从现有的GetAllDDoSFlows函数获取初始数据
	flows := []request.DDoSFlowRequest{
		{
			IP: "192.168.0.11", Protocol: 6, FlowDuration: 546328, FwdPackets: 7, FlowType: "正常流量",
			Time: time.Date(2025, 6, 21, 8, 47, 3, 920*1e6, time.UTC),
			Features: request.FeaturesRequest{
				Protocol: 6, FlowDuration: 546328, TotalFwdPackets: 7, TotalBackwardPackets: 2,
				FwdPacketsLengthTotal: 756.0, FwdPacketLengthMax: 369.0, FwdPacketLengthMin: 0.0, FwdPacketLengthStd: 178.31714,
				BwdPacketLengthMax: 0.0, BwdPacketLengthMin: 0.0, FlowIATMean: 68291.0, FlowIATMin: 1.0,
				BwdIATMean: 2.0, BwdIATMin: 2.0, FwdPSHFlags: 0, FwdHeaderLength: 164, BwdHeaderLength: 64,
				BwdPacketsPerSecond: 3.6608045, SYNFlagCount: 0, URGFlagCount: 0, CWEFlagCount: 0, DownUpRatio: 0.0,
				InitFwdWinBytes: 8192, InitBwdWinBytes: 29200, ActiveMean: 0.0, ActiveStd: 0.0, IdleStd: 0.0,
			},
		},
		{
			IP: "192.168.0.12", Protocol: 6, FlowDuration: 3, FwdPackets: 3, FlowType: "正常流量",
			Time: time.Date(2025, 6, 21, 8, 52, 27, 10*1e6, time.UTC),
			Features: request.FeaturesRequest{
				Protocol: 6, FlowDuration: 3, TotalFwdPackets: 3, TotalBackwardPackets: 0,
				FwdPacketsLengthTotal: 0.0, FwdPacketLengthMax: 0.0, FwdPacketLengthMin: 0.0, FwdPacketLengthStd: 0.0,
				BwdPacketLengthMax: 0.0, BwdPacketLengthMin: 0.0, FlowIATMean: 1.5, FlowIATMin: 1.0,
				BwdIATMean: 0.0, BwdIATMin: 0.0, FwdPSHFlags: 0, FwdHeaderLength: 64, BwdHeaderLength: 0,
				BwdPacketsPerSecond: 0.0, SYNFlagCount: 2, URGFlagCount: 0, CWEFlagCount: 0, DownUpRatio: 0.0,
				InitFwdWinBytes: 512, InitBwdWinBytes: 0, ActiveMean: 0.0, ActiveStd: 0.0, IdleStd: 0.0,
			},
		},
		{
			IP: "192.168.0.33", Protocol: 17, FlowDuration: 45301, FwdPackets: 2, FlowType: "正常流量",
			Time: time.Date(2025, 6, 21, 9, 33, 42, 980*1e6, time.UTC),
			Features: request.FeaturesRequest{
				Protocol: 17, FlowDuration: 45301, TotalFwdPackets: 2, TotalBackwardPackets: 2,
				FwdPacketsLengthTotal: 62.0, FwdPacketLengthMax: 31.0, FwdPacketLengthMin: 31.0, FwdPacketLengthStd: 0.0,
				BwdPacketLengthMax: 159.0, BwdPacketLengthMin: 159.0, FlowIATMean: 15100.333, FlowIATMin: 1.0,
				BwdIATMean: 1.0, BwdIATMin: 1.0, FwdPSHFlags: 0, FwdHeaderLength: 40, BwdHeaderLength: 862,
				BwdPacketsPerSecond: 44.149136, SYNFlagCount: 0, URGFlagCount: 0, CWEFlagCount: 0, DownUpRatio: 1.0,
				InitFwdWinBytes: -1, InitBwdWinBytes: -1, ActiveMean: 0.0, ActiveStd: 0.0, IdleStd: 0.0,
			},
		},
		{
			IP: "192.168.0.43", Protocol: 17, FlowDuration: 32405, FwdPackets: 2, FlowType: "正常流量",
			Time: time.Date(2025, 6, 21, 9, 18, 12, 120*1e6, time.UTC),
			Features: request.FeaturesRequest{
				Protocol: 17, FlowDuration: 32405, TotalFwdPackets: 2, TotalBackwardPackets: 2,
				FwdPacketsLengthTotal: 82.0, FwdPacketLengthMax: 41.0, FwdPacketLengthMin: 41.0, FwdPacketLengthStd: 0.0,
				BwdPacketLengthMax: 57.0, BwdPacketLengthMin: 57.0, FlowIATMean: 10801.667, FlowIATMin: 1.0,
				BwdIATMean: 50.0, BwdIATMin: 50.0, FwdPSHFlags: 0, FwdHeaderLength: 0, BwdHeaderLength: 28,
				BwdPacketsPerSecond: 61.718872, SYNFlagCount: 0, URGFlagCount: 0, CWEFlagCount: 0, DownUpRatio: 1.0,
				InitFwdWinBytes: -1, InitBwdWinBytes: -1, ActiveMean: 0.0, ActiveStd: 0.0, IdleStd: 0.0,
			},
		},
	}

	// 转换为DTO并插入数据库
	var flowsDTO []ddos.InsertDDoSFlowParams
	for _, flow := range flows {
		flowsDTO = append(flowsDTO, dto.DDoSFlowRequest2DTO(&flow))
	}

	err := s.AddDDoSFlowsBatch(ctx, flowsDTO)
	if err != nil {
		logrus.Errorf("[InitializeDDoSFlowsData] - failed to initialize ddos flows data: %v", err)
		return err
	}

	logrus.Debugf("[InitializeDDoSFlowsData] - successfully initialized %d ddos flows", len(flowsDTO))
	return nil
}
